import Vue from 'vue'
import {
  baseService,
  arrayTools
} from '@/service/common/baseService'
import tools from '@/service/common/tools'

var FormValidator = {};

/**添加自定义规则，可覆盖默认规则**/
FormValidator.addRuls = function (key, rule) {
  FormValidator.rules[key] = rule;
}

/**
 * 校验处理入口
 */
FormValidator.doValidate = function (el, binding, vnode, value) {
  if (vnode.data.attrs.desc === '控件测试-单选框') {
  }
  if (vnode.data.attrs.desc.indexOf('与企业关系') != -1) {
  }
  //获取dom上的value，change事件直接拿value。keyup就算了
  if (value === undefined || el.type === "radio") {
    var value = getElemetValue(vnode);
    if (value === "___skip___") return;
  }
  var validateJson = binding.value;
  if (vnode.elm.required) {
    validateJson.required = true;
  }

  // 隐藏状态下当前字段permission必须存在且为n
  let directives = vnode.data.directives
  directives.forEach((v, i) => {
    if (v.name == 'ab-permission') {
      if (v.value == 'n') {
        validateJson.required = false;
      }
    }
  })
  // if ((vnode.data.directives.length == 1 && vnode.data.attrs['ab-permission'] == 'n') || (vnode.data.directives.length > 1 && vnode.data.directives[1].value == 'n')) {
  //
  // }

  if (validateJson.required) {         //如果当前表单有必填的规则，则在前面设置样式
    setRequire(vnode)
  }

  // 执行校验
  var validity = validRules(value, validateJson, vnode.data.attrs.desc);
  // if(vnode.data.attrs.desc == '申请金额') {
  //   debugger
  // }
  //添加校验标记
  setValidity(validity, vnode);
}

function setRequire(vnode) {     //如果当前表单有必填的校验，则在前面添加类
  //console.log("vnode.elm.parentNode.parentNode",vnode.elm.parentNode.parentNode)
  vnode.elm.parentNode.parentNode.firstChild.classList.add("ivu-form-item-require")
}

//只会在第一次时才会需要获取值
function getElemetValue(vnode) {
  //说明已渲染，则直接获取value即可
  if (vnode.data.model) {
    return vnode.data.model.value || vnode.elm.value;
  }

  for (var i = 0, d; d = vnode.data.directives[i++];) {
    if (d.name == "model") {
      if (d.oldValue === d.value && typeof d.value !== 'undefined') {
        return "___skip___";
      }
      return d.value;
    }
  }

  console.error("ab-validate 指令依赖 v-model 或者 :model 指令", vnode.elm)
  return "___skip___";
}

//设置校验标记
function setValidity(validity, vnode) {
  var formContext = vnode.context;

  if (!formContext.$validity) {
    formContext.$validity = {};
  }

  if (!vnode.data.attrs.desc) {
    //获取model 的key作为标识
  }
  //console.log("必填校验------", vnode)
  if (validity === true) {
    delete formContext.$validity[vnode.data.attrs.desc];

    vnode.elm.classList.remove("ab-invalid");
    vnode.elm.classList.add("ab-valid");

  } else {
    formContext.$validity[vnode.data.attrs.desc] = validity;
    if (vnode.data.attrs.desc == '申请金额') {
      console.log(vnode.data.attrs.desc, validity, formContext)
    }
    vnode.elm.classList.add("ab-invalid");
    vnode.elm.classList.remove("ab-valid");
  }
}


/**
 * 校验入口
 * @param value
 * @param validRule
 * @returns
 */
function validRules(value, validRule, desc) {
  value = value == null ? "" : value + "";

  if (typeof value == 'string') {
    value = value.trim();
  }
  // 获取json。
  var json = validRule;
  if (typeof json == 'string') {
    json = eval('(' + validRule + ')');
  }

  var isRequired = json.required;

  // 非必填的字段且值为空 那么直接返回成功。
  if ((isRequired == false || isRequired == undefined) && value == "") {
    return true;
  }

  //number：true将number取消格式化
  if (json.number) {
    // value = Vue.tools.toNumber(value) + "";
  }

  // 遍历json规则。
  var validates = [];
  for (var name in json) {
    var validValue = json[name];
    validates.push({
      ruleName: name, // 规则名称
      validValue: validValue, //验证的值
      value: value, //实际的值
      desc: desc
    });
  }

  //验证规则
  for (var i = 0, v; v = validates[i++];) {
    if (i == validates.length) v.isLast = true;
    var _valid = doValidate(v);
    //如果当前规则验证不通过则直接返回 错误信息
    if (_valid !== true) return _valid;
  }

  //全部验证通过则返回true
  return true;

}

/**
 * 执行校验
 * @param conf
 * @returns
 */
function doValidate(conf) {
  var _valid = true,
    ruleName = conf.ruleName.toLowerCase(), // 规则名称
    validValue = conf.validValue, //验证的值
    value = conf.value, //实际的值
    desc = conf.desc
  var rule = FormValidator.rules[ruleName];

  if (!rule) return true;

  // 验证规则如下：
  // email:true,url:true.
  //验证规则是boolean类型
  if (typeof validValue === "boolean") {
    _valid = (!rule.rule(value, validValue) && validValue == true) ? false : true;
  } else
    _valid = rule.rule(value, validValue);

  //校验不通过时，返回错误信息
  if (!_valid) {
    let templateType = '001'
    if (rule.templateType) {
      templateType = rule.templateType
    }
    var errMsg = FormValidator.format(rule.msg, validValue, desc, templateType);
    return errMsg;
  }

  /*if(conf.isLast && element.attr("desc")){
  	element.removeAttr("error-msg");
  }*/
  return _valid;
}

FormValidator.format = function (msg, args, desc, templateType) {
  //boolean类型的直接返回

  if (typeof args === "boolean") {
    if (templateType == '001') {
      msg = `${desc}${msg}`
    } else if (templateType == '002') {
      msg = `${msg}${desc}`
    }
    return msg;
  }
  if (typeof args == 'object' && args.target) {
    args = args.targetVal;
  }
  if (!(args instanceof Array)) {
    args = [args];
  }
  //数组类型的
  for (let i = 0; i < args.length; i++) {
    msg = msg.replace(RegExp("\\{" + (i) + "\\}", "g"), args[i]);
  }
  let errorMsg = ''
  if (templateType == '001') {
    errorMsg = `${desc}${msg}`
  } else if (templateType == '002') {
    errorMsg = `${msg}${desc}`
  } else {
    errorMsg = msg
  }
  return errorMsg;
}


FormValidator.rules = {
  "required": {
    rule: function (v) {
      if (v == "" || v.length == 0)
        return false;
      return true;
    },
    title: "必填",
    formRule: true,
    msg: "请输入",
    templateType: '002'
  },
  "number": {
    rule: function (v) {
      return /^-?((\d{1,3}(,\d{3})+?|\d+)(\.\d{1,5})?)$/
        .test(v.trim());
    },
    title: "数字",
    formRule: true,
    msg: "只能输入数字"
  },
  "variable": {
    rule: function (v) {
      return /^[A-Za-z_]*$/gi.test(v.trim());
    },
    title: "字母或下划线",
    formRule: true,
    msg: "只能是字母和下划线"
  },
  "fields": {
    rule: function (v) {
      return /^[A-Za-z]{1}([a-zA-Z0-9_]{1,17})?$/gi.test(v.trim());
    },
    msg: "首字符为英文字母且最大长度为18"
  },
  "minlength": {
    rule: function (v, b) {
      return (v.length >= b);
    },
    msg: "长度不少于{0}"
  },
  "maxlength": {
    rule: function (v, b) {
      return (v.trim().length <= b);
    },
    msg: "长度不超过{0}"
  },
  "rangelength": {
    rule: function (v, args) {
      return (v.trim().length >= args[0] && v.trim().length <= args[1]);
    },
    msg: "长度必须在{0}之{1}间"
  },
  "email": {
    rule: function (v) {
      return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i
        .test(v.trim());
    },
    title: "email",
    formRule: true,
    msg: "请输入正确的",
    templateType: '002'
  },
  "url": {
    rule: function (v) {
      return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i
        .test(v.trim());
    },
    title: "url",
    formRule: true,
    msg: "请输入正确的",
    templateType: '002'
  },
  "date": {
    rule: function (v) {
      var re =
        /^([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))/g
          .test(v.trim());
      return re;
    },
    title: "日期",
    formRule: true,
    msg: "请输入合法的",
    templateType: '002'
  },
  "time": {
    rule: function (v) {
      var re = /^(?:[01]?\d|2[0-3])(?::[0-5]?\d){2}$/g
        .test(v.trim());
      return re;
    },
    title: "时间",
    formRule: true,
    msg: "请输入合法的",
    templateType: '002'
  },
  "chinese": {
    rule: function (v) {
      var re = /[\u4E00-\u9FA5\uF900-\uFA2D]/
        .test(v.trim());
      return re;
    },
    title: "汉字",
    formRule: true,
    msg: "只能为中文汉字"
  },
  "qq": {
    rule: function (v) {
      return /^[1-9]*[1-9][0-9]*$/i.test(v.trim());
    },
    title: "QQ号",
    formRule: true,
    msg: "请输入正确的",
    templateType: '002'
  },
  "phonenumber": {
    rule: function (v) {
      if (v.length > 11) return false;
      return /((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)/i
        .test(v.trim());
    },
    title: "手机号码",
    formRule: true,
    msg: "请输入正确的",
    templateType: '002'
  },
  "digits": {
    rule: function (v) {
      return /^\d+$/.test(v.trim());
    },
    title: "整数",
    formRule: true,
    msg: "只能为整数"
  },
  "equalto": {
    rule: function (v, b) {
      var a = $("#" + b).val();
      return (v.trim() == a.trim());
    },
    msg: "两次输入不等"
  },
  "range": {
    rule: function (v, args) {
      return v <= args[1] && v >= args[0];
    },
    msg: "只能为{0}到{1}范围之内的数字"
  },
  "maxvalue": {
    rule: function (v, max) {
      return Number(v) <= Number(max);
    },
    msg: "输入的值不能大于{0}"
  },
  "minvalue": {
    rule: function (v, min) {
      return Number(v) >= Number(min);
    },
    msg: "输入的值不能小于{0}"
  },
  "maxintlen": {
    // 判断数字整数位
    rule: function (v, b) {
      return (v + '').split(".")[0].replace("/,/g", "").length <= b;
    },
    msg: "整数位最大长度为{0}"
  },
  "maxdecimallen": {
    // 判断数字小数位
    rule: function (v, b) {
      return (v + '').replace(/^[^.]*[.]*/, '').length <= b;
    },
    msg: "小数位最大长度为{0}"
  },
  "daterangestart": {
    rule: function (v, b, e) {
      return daysBetween(b.targetVal, v);
    },
    msg: "日期必须大于或等于{0}"
  },
  "daterangeend": {
    rule: function (v, b, e) {
      return daysBetween(v, b.targetVal);
    },
    msg: "日期必须小于或等于{0}"
  },
  "empty": {
    // 空的字段（永远通过验证,返回true）  防止在验证JSON中出现有多余的逗号
    rule: function (v, b) {
      //	var start = $("#" + b).val();
      return true;
    },
    msg: ""
  },
  "nodigitsstart": {
    // 不能以数字开头
    rule: function (v) {
      return !/^(\d+)(.*)$/.test(v.trim());
    },
    title: "不以数字开头",
    formRule: true,
    msg: "不能以数字开头"
  },
  "varirule": {
    name: "varirule",
    rule: function (v) {
      return /^[a-zA-Z]\w*$/.test(v.trim());
    },
    title: "以字母开头",
    formRule: true,
    msg: "只能为字母开头,允许字母、数字和下划线"
  },
  /**
   * eg:<input type="text" ng-model="data.name" ht-validate="{isexist:'bOEnt/isExist'}"/>
   * isexist:是请求地址的参数，需要自己实现，要验证的数据参数是‘key’；
   * 返回true:代表已存在，不可用；返回false:不存在，可用
   */
  "isexist": {
    name: "isexist",
    rule: function (v, url) {
      if (!v) return true;
      var b;
      if (url.indexOf("?") < 1) {
        url += "?";
      }
      $.ajax({
        url: url + "&key=" + v,
        type: 'POST',
        dataType: 'json',
        async: false,
        success: function (result) {
          b = !result;
        }
      });
      return b;
    },
    msg: "数据已被使用,请重新填写"
  },
  "companyname": {
    name: "companyname",
    rule: function (v) {
      return /^(?!\s*$)[A-Za-z0-9._\-\(\)\u4e00-\u9fa5\（）-]+$/gi.test(v.trim());
    },
    title: "公司名称校验",
    formRule: true,
    msg: "只能为中文字符、英文字母、数字、-、_、.、和中英文圆括号组成",
  },
  // "address": {
  //   name: "address",
  //   rule: function(v) {
  //     return /^(?!\s*$)[A-Za-z0-9._，。\u4e00-\u9fa5\-]+$/gi.test(v.trim());
  //   },
  //   title: "地址校验",
  //   formRule: true,
  //   msg: "只能为中英文、整数数字、符号组成"
  // },
  "name": {
    name: "name",
    rule: function (v) {
      return /^[\u4e00-\u9fa5\·]+$/gi.test(v.trim());
    },
    title: "姓名校验",
    formRule: true,
    msg: "只能为中文和·组成 "
  },
  "newphonenumber": {
    name: "newphonenumber",
    rule: function (v) {
      return /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/gi.test(v.trim())
    },
    title: "11位手机号码校验",
    formRule: true,
    msg: "请输入11位正确",
    templateType: '002'
  },
  "idcardnumber": {
    name: "idcardnumber",
    rule: function (v) {
      return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/gi.test(v.trim())
    },
    title: "身份证号码校验",
    formRule: true,
    msg: "请输入正确的",
    templateType: '002'
  },
  'alphabet': {
    name: '大小字母',
    rule: function (v) {
      return /^[A-Za-z0-9]*$/gi.test(v.trim());
    },
    title: '大小字母',
    formRule: true,
    msg: '只能是大小字母和数字组成'
  }
}

export default FormValidator;
